package com.zjmzxfzhl.modules.app.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zjmzxfzhl.common.core.constant.SysConstants;
import com.zjmzxfzhl.common.core.exception.SysException;
import com.zjmzxfzhl.common.core.util.CommonUtil;
import com.zjmzxfzhl.modules.app.entity.*;
import com.zjmzxfzhl.modules.app.form.AppDocVo;
import com.zjmzxfzhl.modules.app.form.DirCrumbVo;
import com.zjmzxfzhl.modules.app.form.DirIsLeafVo;
import com.zjmzxfzhl.modules.app.form.TaskCrumbVo;
import com.zjmzxfzhl.modules.app.service.*;
import com.zjmzxfzhl.modules.sys.entity.vo.ElTree;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zjmzxfzhl.common.core.base.BaseServiceImpl;
import com.zjmzxfzhl.modules.app.entity.AppDir;
import com.zjmzxfzhl.modules.app.mapper.AppDirMapper;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * Service
 * 
 * @author 张森荣
 */
@Service
public class AppDirServiceImpl extends BaseServiceImpl<AppDirMapper, AppDir>
        implements AppDirService {
    @Autowired
    private AppDocService appDocService;
    @Autowired
    private AppTaskService appTaskService;
    @Autowired
    private AppProjService appProjService;
    @Autowired
    private AppProdService appProdService;

    @Override
    public IPage<AppDir> list(IPage<AppDir> page, AppDir appDir) {
        return page.setRecords(baseMapper.list(page, appDir));
    }
    @Override
    public List<AppDir> getList(IPage<AppDir> page, AppDir appDir) {
        return baseMapper.list(page, appDir);
    }
    @Override
    public Integer selectRowCount(AppDir appDir) {
        return baseMapper.selectRowCount(appDir);
    }

    public List<DirIsLeafVo> dirIsLeaf() {
        return baseMapper.dirIsLeaf();
    }
    /**
     * 新增项目，自动计算机构级别、机构级次码、是否叶子
     *
     * @param appDir
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveAppDir(AppDir appDir) {
//        String uuid = UUID.randomUUID().toString().replaceAll("-","");
//        appDir.setDirId(uuid);
        appDir =setAppDir(appDir);
        Boolean result = this.save(appDir);
        if(result==false){
            return result;
        }
        // 【1】 校验id是否重复.
        if (CommonUtil.isEmptyStr(appDir.getParentDirId())) {
            appDir.setDirLevel("1");
            appDir.setDirLevelCode(appDir.getDirId());
            appDir.setIsLeaf(SysConstants.USER_STATUS_1);
            result = this.updateById(appDir);
            return result;
        } else {

            // 父节点
            AppDir parentAppDir = this.getById(appDir.getParentDirId());
            if (parentAppDir == null) {
                throw new SysException("保存失败,上级机构ID【" + appDir.getParentDirId() + "】不存在!");
            }
            // 【2】计算机构级次,机构级次码
            // 【2-a】设置新增机构的父机构是否叶子为否
            if (!SysConstants.IS_LEAF_0.equals(parentAppDir.getIsLeaf())) {
                parentAppDir.setIsLeaf(SysConstants.IS_LEAF_0);
                this.updateById(parentAppDir);
            }
            Integer DirLevel = Integer.valueOf(parentAppDir.getDirLevel()) + 1;
            appDir.setDirLevel(DirLevel.toString());
            appDir.setDirLevelCode(parentAppDir.getDirLevelCode() + "," + appDir.getDirId());

            // 【3】设置新增机构是否叶子为 是；
            appDir.setIsLeaf("1");
            result = this.updateById(appDir);
        }
        return result;
    }
    private AppDir setAppDir(AppDir appDir){
        if (appDir.getDirLevel() == null || "".equals(appDir.getDirLevel())) {
            appDir.setDirLevel("0");
        }
        if (appDir.getDirLevelCode() == null) {
            appDir.setDirLevelCode("");
        }
        return appDir;
    }

    /**
     * 移动项目树，自动计算机构级别、机构级次码、是否叶子
     *
     * @param appDir
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean moveTree(AppDir appDir,String parentId) {
        Boolean result = true;

        if (CommonUtil.isEmptyStr(appDir.getParentDirId())) {
            appDir.setDirLevel("1");
            appDir.setDirLevelCode(appDir.getDirId());
            result = this.updateById(appDir);
        } else {
            // 父节点
            AppDir parentAppDir = this.getById(appDir.getParentDirId());
            if (parentAppDir == null) {
                throw new SysException("保存失败,上级机构ID【" + parentAppDir.getParentDirId() + "】不存在!");
            }
            // 【2】计算机构级次,机构级次码
            // 【2-a】设置新增机构的父机构是否叶子为否
            if (!SysConstants.IS_LEAF_0.equals(parentAppDir.getIsLeaf())) {
                parentAppDir.setIsLeaf(SysConstants.IS_LEAF_0);
                this.updateById(parentAppDir);
            }
            Integer DirLevel = Integer.valueOf(parentAppDir.getDirLevel()) + 1;
            appDir.setDirLevel(DirLevel.toString());
            appDir.setDirLevelCode(parentAppDir.getDirLevelCode() + "," + appDir.getDirId());
            result = this.updateById(appDir);
        }
        if (result == true) {
            //不为叶子节点时更改子树的层级，路径
            if (SysConstants.IS_LEAF_0.equals(appDir.getIsLeaf())) {
                AppDir selectDir = new AppDir();
                selectDir.setDirLevelCode(appDir.getDirId());

                List<AppDir> appDirList = baseMapper.list(null, selectDir);
                if (appDirList.size() > 0) {
                    for (AppDir Dir : appDirList) {
                        if (Dir.getDirLevelCode().indexOf(appDir.getDirId()) != -1) {
                            //替换树路径
                            int sub = Dir.getDirLevelCode().indexOf(appDir.getDirId()) + appDir.getDirId().length();
                            Dir.setDirLevelCode(appDir.getDirLevelCode() + Dir.getDirLevelCode().substring(sub));
                            //根据树路径修改层级
                            String[] codeArr = Dir.getDirLevelCode().split(",");
                            Integer level = codeArr.length;
                            Dir.setDirLevel(level.toString());
                            this.updateById(Dir);
                        }
                    }
                }
            }
        }

        //判断原父节点是否成为新为叶子
        System.out.println(parentId);
        if (parentId != null && !"".equals(parentId)) {
            inspectParent(parentId);
        }
        return result;
    }


    /**
     * 项目管理，项目树数据
     *
     * @return
     */
    @Override
    public List<ElTree> getTreeData( AppDir appDir, String parentId, Integer level) {
        List<AppDir> DirList=null;
        if (parentId == null && level == null) {
            //查找一级节点
            appDir.setDirLevel("1");
            DirList = baseMapper.list(null, appDir);
        }else
        {//按层级展开节点
            Integer parentLevel=null;
            if(parentId!=null&&!"".equals(parentId)){
                AppDir parentAppDir=this.getById(parentId);
                parentLevel=Integer.valueOf(parentAppDir.getDirLevel());
            }
            DirList = baseMapper.treeData(parentId,level,parentLevel);
        }
        if (DirList != null) {
            return makeOrgTree(DirList);
        }
        return null;
    }

    /**
     * 生成项目树
     *
     * @param DirList
     * @return
     */
    public List<ElTree> makeOrgTree(List<AppDir> DirList) {
        Map<String, ElTree> orgMap = new LinkedHashMap<String, ElTree>();
        for (AppDir appDir : DirList) {
            ElTree elTree = new ElTree();
            elTree.setId(appDir.getDirId());
            elTree.setLabel(appDir.getName());
            elTree.setIsLeaf("1".equals(appDir.getIsLeaf()));
            elTree.setData(appDir);
            orgMap.put(appDir.getDirId(), elTree);
            if (CommonUtil.isNotEmptyStr(appDir.getParentDirId()) && orgMap.containsKey(appDir.getParentDirId())) {
                elTree.setParentId(appDir.getParentDirId());
                ElTree parentElTree = orgMap.get(appDir.getParentDirId());
                parentElTree.addChildren(elTree);
            }
        }

        List<ElTree> result = new ArrayList<ElTree>();
        orgMap.forEach((k, v) -> {
            if (CommonUtil.isEmptyStr(v.getParentId())) {
                result.add(v);
            }
        });
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delByIds(String ids) {
        Boolean result = true;
        String[] idsArr = ids.split(",");

        result = isRemove(idsArr);
        if (result == false) {
            return result;
        }
        for (String s:idsArr) {
            AppDir appDir=baseMapper.selectById(s);
            result= this.removeById(s);
            if (appDir.getParentDirId() != null && !"".equals(appDir.getParentDirId())) {
                inspectParent(appDir.getParentDirId());
            }
        }
        return result;
    }

    private boolean isRemove(String[] idsArr){
        Boolean result = true;
        for (String s:idsArr) {
            AppDir appDir = baseMapper.selectById(s);
            //目录不存在
            if (appDir == null) {
                result = false;
            }
            //不为叶子节点
            if ("0".equals(appDir.getIsLeaf())) {
                result = false;
            }
            //判断是否存在文件
            AppDocVo appDoc = new AppDocVo();
            appDoc.setDirId(s);
            appDoc.setDeleted("0");
            Integer doc = appDocService.selectRowCount(appDoc);
            if (doc > 0) {
                result = false;
            }
            if (appDir.getDirType() != null) {
                switch (appDir.getDirType()) {
                    case "00": {//项目
                        Integer total = appProjService.count(new LambdaQueryWrapper<AppProj>().eq(AppProj::getDirId, s));
                        if (total > 0) {
                            result = false;
                        }
                    }
                    break;
                    case "01": {//任务
                        Integer total = appTaskService.count(new LambdaQueryWrapper<AppTask>().eq(AppTask::getDirId, s));
                        if (total > 0) {
                            result = false;
                        }
                    }
                    break;
                    case "02": {//产品
                        Integer total = appProdService.count(new LambdaQueryWrapper<AppProd>().eq(AppProd::getDirId, s));
                        if (total > 0) {
                            result = false;
                        }
                    }
                    break;
                    case "04": {//企业

                    }
                    break;
                    case "05": {//合同

                    }
                    break;
                    case "06": {//知识库

                    }
                    break;
                }
            }
        }
        return result;
    }

    /**
     * 返回单一树结构
     *
     * @return
     */
    public ElTree resultTree(String id) {
        AppDir appDir = this.getById(id);
        ElTree elTree = new ElTree();
        elTree.setId(appDir.getDirId());
        elTree.setLabel(appDir.getName());
        elTree.setParentId(appDir.getParentDirId());
        elTree.setIsLeaf("1".equals(appDir.getIsLeaf()));
        elTree.setData(appDir);

        return elTree;
    }

    //检查父节点是否为子树
    private void inspectParent(String parentId){
        Integer total = this.count(new LambdaQueryWrapper<AppDir>().eq(AppDir::getParentDirId, parentId));
        if (total <= 0) {
            AppDir parentAppDir=this.getById(parentId);
            parentAppDir.setIsLeaf(SysConstants.USER_STATUS_1);
            this.updateById(parentAppDir);
        }
    }

    /**
     * 面包屑导航
     *
     * @return
     */
    public List<DirCrumbVo> dirCrumb(String dirId) {
        List<DirCrumbVo> result=new ArrayList<>();
        List<DirCrumbVo> dirCrumbVoList=baseMapper.dirCrumb(dirId);
        if(dirCrumbVoList.size()>0){
            if(dirCrumbVoList.get(0).getParentDirId()!=null){
                result.addAll(dirCrumb(dirCrumbVoList.get(0).getParentDirId()));
            }
            result.add(dirCrumbVoList.get(0));
        }
//        Collections.reverse(result);
        return result;
    }
}
